home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / ftp / RCS / cmds.c,v < prev    next >
Encoding:
Text File  |  1992-03-18  |  41.6 KB  |  2,399 lines

  1. head     1.4;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    shirriff:1.4; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.4
  10. date     91.11.11.19.47.36;  author shirriff;  state Exp;
  11. branches ;
  12. next     1.3;
  13.  
  14. 1.3
  15. date     90.10.27.13.48.29;  author shirriff;  state Exp;
  16. branches ;
  17. next     1.2;
  18.  
  19. 1.2
  20. date     88.07.21.09.57.39;  author ouster;  state Exp;
  21. branches ;
  22. next     1.1;
  23.  
  24. 1.1
  25. date     88.07.20.14.26.33;  author ouster;  state Exp;
  26. branches ;
  27. next     ;
  28.  
  29.  
  30. desc
  31. @@
  32.  
  33.  
  34. 1.4
  35. log
  36. @Fixed problem with free of things that shouldn't be freed.
  37. @
  38. text
  39. @/*
  40.  * Copyright (c) 1985, 1989 Regents of the University of California.
  41.  * All rights reserved.
  42.  *
  43.  * Redistribution and use in source and binary forms are permitted
  44.  * provided that the above copyright notice and this paragraph are
  45.  * duplicated in all such forms and that any documentation,
  46.  * advertising materials, and other materials related to such
  47.  * distribution and use acknowledge that the software was developed
  48.  * by the University of California, Berkeley.  The name of the
  49.  * University may not be used to endorse or promote products derived
  50.  * from this software without specific prior written permission.
  51.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  52.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  53.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  54.  */
  55.  
  56. #ifndef lint
  57. static char sccsid[] = "@@(#)cmds.c    5.16 (Berkeley) 3/21/89";
  58. #endif /* not lint */
  59.  
  60. /*
  61.  * FTP User Program -- Command Routines.
  62.  */
  63. #include <sys/param.h>
  64. #include <sys/wait.h>
  65. #include <sys/stat.h>
  66. #include <sys/socket.h>
  67.  
  68. #include <arpa/ftp.h>
  69.  
  70. #include <signal.h>
  71. #include <stdio.h>
  72. #include <errno.h>
  73. #include <netdb.h>
  74. #include <ctype.h>
  75. #include <time.h>
  76.  
  77. #include "ftp_var.h"
  78.  
  79.  
  80. extern    char *globerr;
  81. extern    char **glob();
  82. extern    char *home;
  83. extern    char *remglob();
  84. extern    char *getenv();
  85. extern    char *index();
  86. extern    char *rindex();
  87. extern off_t restart_point;
  88. extern char reply_string[];
  89.  
  90. char *mname;
  91. jmp_buf jabort;
  92. char *dotrans(), *domap();
  93.  
  94. /*
  95.  * Connect to peer server and
  96.  * auto-login, if possible.
  97.  */
  98. setpeer(argc, argv)
  99.     int argc;
  100.     char *argv[];
  101. {
  102.     char *host, *hookup();
  103.     int port;
  104.  
  105.     if (connected) {
  106.         printf("Already connected to %s, use close first.\n",
  107.             hostname);
  108.         code = -1;
  109.         return;
  110.     }
  111.     if (argc < 2) {
  112.         (void) strcat(line, " ");
  113.         printf("(to) ");
  114.         (void) gets(&line[strlen(line)]);
  115.         makeargv();
  116.         argc = margc;
  117.         argv = margv;
  118.     }
  119.     if (argc > 3) {
  120.         printf("usage: %s host-name [port]\n", argv[0]);
  121.         code = -1;
  122.         return;
  123.     }
  124.     port = sp->s_port;
  125.     if (argc > 2) {
  126.         port = atoi(argv[2]);
  127.         if (port <= 0) {
  128.             printf("%s: bad port number-- %s\n", argv[1], argv[2]);
  129.             printf ("usage: %s host-name [port]\n", argv[0]);
  130.             code = -1;
  131.             return;
  132.         }
  133.         port = htons(port);
  134.     }
  135.     host = hookup(argv[1], port);
  136.     if (host) {
  137.         connected = 1;
  138.         if (autologin) {
  139.             int overbose;
  140.  
  141.             (void) login(argv[1]);
  142. #if defined(unix) && NBBY == 8
  143. /*
  144.  * this ifdef is to keep someone form "porting" this to an incompatible
  145.  * system and not checking this out. This way they have to think about it.
  146.  */
  147.             overbose = verbose;
  148.             if (debug == 0)
  149.                 verbose = -1;
  150.             if (command("SYST") == COMPLETE && overbose) {
  151.                 register char *cp, c;
  152.                 cp = index(reply_string+4, ' ');
  153.                 if (cp == NULL)
  154.                     cp = index(reply_string+4, '\r');
  155.                 if (cp) {
  156.                     if (cp[-1] == '.')
  157.                         cp--;
  158.                     c = *cp;
  159.                     *cp = '\0';
  160.                 }
  161.  
  162.                 printf("Remote system type is %s.\n",
  163.                     reply_string+4);
  164.                 if (cp)
  165.                     *cp = c;
  166.             }
  167.             if (!strncmp(reply_string, "215 UNIX Type: L8", 17)) {
  168.                 setbinary();
  169.                 if (overbose)
  170.                     printf("Using %s mode to transfer files.\n",
  171.                     typename);
  172.             } else if (overbose && 
  173.                 !strncmp(reply_string, "215 TOPS20", 10)) {
  174.                 printf(
  175. "Remember to set tenex mode when transfering binary files from this machine.\n");
  176.             }
  177.             verbose = overbose;
  178. #endif /* unix */
  179.         }
  180.     }
  181. }
  182.  
  183. struct    types {
  184.     char    *t_name;
  185.     char    *t_mode;
  186.     int    t_type;
  187.     char    *t_arg;
  188. } types[] = {
  189.     { "ascii",    "A",    TYPE_A,    0 },
  190.     { "binary",    "I",    TYPE_I,    0 },
  191.     { "image",    "I",    TYPE_I,    0 },
  192.     { "ebcdic",    "E",    TYPE_E,    0 },
  193.     { "tenex",    "L",    TYPE_L,    bytename },
  194.     0
  195. };
  196.  
  197. /*
  198.  * Set transfer type.
  199.  */
  200. settype(argc, argv)
  201.     char *argv[];
  202. {
  203.     register struct types *p;
  204.     int comret;
  205.  
  206.     if (argc > 2) {
  207.         char *sep;
  208.  
  209.         printf("usage: %s [", argv[0]);
  210.         sep = " ";
  211.         for (p = types; p->t_name; p++) {
  212.             printf("%s%s", sep, p->t_name);
  213.             if (*sep == ' ')
  214.                 sep = " | ";
  215.         }
  216.         printf(" ]\n");
  217.         code = -1;
  218.         return;
  219.     }
  220.     if (argc < 2) {
  221.         printf("Using %s mode to transfer files.\n", typename);
  222.         code = 0;
  223.         return;
  224.     }
  225.     for (p = types; p->t_name; p++)
  226.         if (strcmp(argv[1], p->t_name) == 0)
  227.             break;
  228.     if (p->t_name == 0) {
  229.         printf("%s: unknown mode\n", argv[1]);
  230.         code = -1;
  231.         return;
  232.     }
  233.     if ((p->t_arg != NULL) && (*(p->t_arg) != '\0'))
  234.         comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
  235.     else
  236.         comret = command("TYPE %s", p->t_mode);
  237.     if (comret == COMPLETE) {
  238.         (void) strcpy(typename, p->t_name);
  239.         type = p->t_type;
  240.     }
  241. }
  242.  
  243. /*
  244.  * Set binary transfer type.
  245.  */
  246. /*VARARGS*/
  247. setbinary()
  248. {
  249.  
  250.     call(settype, "type", "binary", 0);
  251. }
  252.  
  253. /*
  254.  * Set ascii transfer type.
  255.  */
  256. /*VARARGS*/
  257. setascii()
  258. {
  259.  
  260.     call(settype, "type", "ascii", 0);
  261. }
  262.  
  263. /*
  264.  * Set tenex transfer type.
  265.  */
  266. /*VARARGS*/
  267. settenex()
  268. {
  269.  
  270.     call(settype, "type", "tenex", 0);
  271. }
  272.  
  273. /*
  274.  * Set ebcdic transfer type.
  275.  */
  276. /*VARARGS*/
  277. setebcdic()
  278. {
  279.  
  280.     call(settype, "type", "ebcdic", 0);
  281. }
  282.  
  283. /*
  284.  * Set file transfer mode.
  285.  */
  286. /*ARGSUSED*/
  287. setmode(argc, argv)
  288.     char *argv[];
  289. {
  290.  
  291.     printf("We only support %s mode, sorry.\n", modename);
  292.     code = -1;
  293. }
  294.  
  295. /*
  296.  * Set file transfer format.
  297.  */
  298. /*ARGSUSED*/
  299. setform(argc, argv)
  300.     char *argv[];
  301. {
  302.  
  303.     printf("We only support %s format, sorry.\n", formname);
  304.     code = -1;
  305. }
  306.  
  307. /*
  308.  * Set file transfer structure.
  309.  */
  310. /*ARGSUSED*/
  311. setstruct(argc, argv)
  312.     char *argv[];
  313. {
  314.  
  315.     printf("We only support %s structure, sorry.\n", structname);
  316.     code = -1;
  317. }
  318.  
  319. /*
  320.  * Send a single file.
  321.  */
  322. put(argc, argv)
  323.     int argc;
  324.     char *argv[];
  325. {
  326.     char *cmd;
  327.     int loc = 0;
  328.     char *oldargv1, *oldargv2;
  329.  
  330.     if (argc == 2) {
  331.         argc++;
  332.         argv[2] = argv[1];
  333.         loc++;
  334.     }
  335.     if (argc < 2) {
  336.         (void) strcat(line, " ");
  337.         printf("(local-file) ");
  338.         (void) gets(&line[strlen(line)]);
  339.         makeargv();
  340.         argc = margc;
  341.         argv = margv;
  342.     }
  343.     if (argc < 2) {
  344. usage:
  345.         printf("usage:%s local-file remote-file\n", argv[0]);
  346.         code = -1;
  347.         return;
  348.     }
  349.     if (argc < 3) {
  350.         (void) strcat(line, " ");
  351.         printf("(remote-file) ");
  352.         (void) gets(&line[strlen(line)]);
  353.         makeargv();
  354.         argc = margc;
  355.         argv = margv;
  356.     }
  357.     if (argc < 3) 
  358.         goto usage;
  359.     oldargv1 = argv[1];
  360.     oldargv2 = argv[2];
  361.     if (!globulize(&argv[1])) {
  362.         code = -1;
  363.         return;
  364.     }
  365.     /*
  366.      * If "globulize" modifies argv[1], and argv[2] is a copy of
  367.      * the old argv[1], make it a copy of the new argv[1].
  368.      */
  369.     if (argv[1] != oldargv1 && argv[2] == oldargv1) {
  370.         argv[2] = argv[1];
  371.     }
  372.     cmd = (argv[0][0] == 'a') ? "APPE" : ((sunique) ? "STOU" : "STOR");
  373.     if (loc && ntflag) {
  374.         argv[2] = dotrans(argv[2]);
  375.     }
  376.     if (loc && mapflag) {
  377.         argv[2] = domap(argv[2]);
  378.     }
  379.     sendrequest(cmd, argv[1], argv[2],
  380.         argv[1] != oldargv1 || argv[2] != oldargv2);
  381. }
  382.  
  383. /*
  384.  * Send multiple files.
  385.  */
  386. mput(argc, argv)
  387.     char *argv[];
  388. {
  389.     register int i;
  390.     int ointer, (*oldintr)(), mabort();
  391.     extern jmp_buf jabort;
  392.     char *tp;
  393.  
  394.     if (argc < 2) {
  395.         (void) strcat(line, " ");
  396.         printf("(local-files) ");
  397.         (void) gets(&line[strlen(line)]);
  398.         makeargv();
  399.         argc = margc;
  400.         argv = margv;
  401.     }
  402.     if (argc < 2) {
  403.         printf("usage:%s local-files\n", argv[0]);
  404.         code = -1;
  405.         return;
  406.     }
  407.     mname = argv[0];
  408.     mflag = 1;
  409.     oldintr = signal(SIGINT, mabort);
  410.     (void) setjmp(jabort);
  411.     if (proxy) {
  412.         char *cp, *tp2, tmpbuf[MAXPATHLEN];
  413.  
  414.         while ((cp = remglob(argv,0)) != NULL) {
  415.             if (*cp == 0) {
  416.                 mflag = 0;
  417.                 continue;
  418.             }
  419.             if (mflag && confirm(argv[0], cp)) {
  420.                 tp = cp;
  421.                 if (mcase) {
  422.                     while (*tp && !islower(*tp)) {
  423.                         tp++;
  424.                     }
  425.                     if (!*tp) {
  426.                         tp = cp;
  427.                         tp2 = tmpbuf;
  428.                         while ((*tp2 = *tp) != NULL) {
  429.                              if (isupper(*tp2)) {
  430.                                 *tp2 = 'a' + *tp2 - 'A';
  431.                              }
  432.                              tp++;
  433.                              tp2++;
  434.                         }
  435.                     }
  436.                     tp = tmpbuf;
  437.                 }
  438.                 if (ntflag) {
  439.                     tp = dotrans(tp);
  440.                 }
  441.                 if (mapflag) {
  442.                     tp = domap(tp);
  443.                 }
  444.                 sendrequest((sunique) ? "STOU" : "STOR",
  445.                     cp, tp, cp != tp || !interactive);
  446.                 if (!mflag && fromatty) {
  447.                     ointer = interactive;
  448.                     interactive = 1;
  449.                     if (confirm("Continue with","mput")) {
  450.                         mflag++;
  451.                     }
  452.                     interactive = ointer;
  453.                 }
  454.             }
  455.         }
  456.         (void) signal(SIGINT, oldintr);
  457.         mflag = 0;
  458.         return;
  459.     }
  460.     for (i = 1; i < argc; i++) {
  461.         register char **cpp, **gargs;
  462.  
  463.         if (!doglob) {
  464.             if (mflag && confirm(argv[0], argv[i])) {
  465.                 tp = (ntflag) ? dotrans(argv[i]) : argv[i];
  466.                 tp = (mapflag) ? domap(tp) : tp;
  467.                 sendrequest((sunique) ? "STOU" : "STOR",
  468.                     argv[i], tp, tp != argv[i] || !interactive);
  469.                 if (!mflag && fromatty) {
  470.                     ointer = interactive;
  471.                     interactive = 1;
  472.                     if (confirm("Continue with","mput")) {
  473.                         mflag++;
  474.                     }
  475.                     interactive = ointer;
  476.                 }
  477.             }
  478.             continue;
  479.         }
  480.         gargs = glob(argv[i]);
  481.         if (globerr != NULL) {
  482.             printf("%s\n", globerr);
  483.             if (gargs) {
  484.                 blkfree(gargs);
  485.                 free(gargs);
  486.             }
  487.             continue;
  488.         }
  489.         for (cpp = gargs; cpp && *cpp != NULL; cpp++) {
  490.             if (mflag && confirm(argv[0], *cpp)) {
  491.                 tp = (ntflag) ? dotrans(*cpp) : *cpp;
  492.                 tp = (mapflag) ? domap(tp) : tp;
  493.                 sendrequest((sunique) ? "STOU" : "STOR",
  494.                     *cpp, tp, *cpp != tp || !interactive);
  495.                 if (!mflag && fromatty) {
  496.                     ointer = interactive;
  497.                     interactive = 1;
  498.                     if (confirm("Continue with","mput")) {
  499.                         mflag++;
  500.                     }
  501.                     interactive = ointer;
  502.                 }
  503.             }
  504.         }
  505.         if (gargs != NULL) {
  506. #if 1
  507. /*
  508.  * There is a bug here.  Gargs is an array of pointers and blkfree
  509.  * frees this array.  However, they are not generally malloc'd pointers
  510.  * and thus cannot be freed.  Commenting this out may cause a memory
  511.  * leak in some cases, but keeping it in results in erroneous frees.
  512.  */
  513.             blkfree(gargs);
  514. #endif
  515.             free(gargs);
  516.         }
  517.     }
  518.     (void) signal(SIGINT, oldintr);
  519.     mflag = 0;
  520. }
  521.  
  522. reget(argc, argv)
  523.     char *argv[];
  524. {
  525.     (void) getit(argc, argv, 1, "r+w");
  526. }
  527.  
  528. get(argc, argv)
  529.     char *argv[];
  530. {
  531.     (void) getit(argc, argv, 0, restart_point ? "r+w" : "w" );
  532. }
  533.  
  534. /*
  535.  * Receive one file.
  536.  */
  537. getit(argc, argv, restartit, mode)
  538.     char *argv[];
  539.     char *mode;
  540. {
  541.     int loc = 0;
  542.     char *oldargv1, *oldargv2;
  543.  
  544.     if (argc == 2) {
  545.         argc++;
  546.         argv[2] = argv[1];
  547.         loc++;
  548.     }
  549.     if (argc < 2) {
  550.         (void) strcat(line, " ");
  551.         printf("(remote-file) ");
  552.         (void) gets(&line[strlen(line)]);
  553.         makeargv();
  554.         argc = margc;
  555.         argv = margv;
  556.     }
  557.     if (argc < 2) {
  558. usage:
  559.         printf("usage: %s remote-file [ local-file ]\n", argv[0]);
  560.         code = -1;
  561.         return (0);
  562.     }
  563.     if (argc < 3) {
  564.         (void) strcat(line, " ");
  565.         printf("(local-file) ");
  566.         (void) gets(&line[strlen(line)]);
  567.         makeargv();
  568.         argc = margc;
  569.         argv = margv;
  570.     }
  571.     if (argc < 3) 
  572.         goto usage;
  573.     oldargv1 = argv[1];
  574.     oldargv2 = argv[2];
  575.     if (!globulize(&argv[2])) {
  576.         code = -1;
  577.         return (0);
  578.     }
  579.     if (loc && mcase) {
  580.         char *tp = argv[1], *tp2, tmpbuf[MAXPATHLEN];
  581.  
  582.         while (*tp && !islower(*tp)) {
  583.             tp++;
  584.         }
  585.         if (!*tp) {
  586.             tp = argv[2];
  587.             tp2 = tmpbuf;
  588.             while ((*tp2 = *tp) != NULL) {
  589.                 if (isupper(*tp2)) {
  590.                     *tp2 = 'a' + *tp2 - 'A';
  591.                 }
  592.                 tp++;
  593.                 tp2++;
  594.             }
  595.             argv[2] = tmpbuf;
  596.         }
  597.     }
  598.     if (loc && ntflag)
  599.         argv[2] = dotrans(argv[2]);
  600.     if (loc && mapflag)
  601.         argv[2] = domap(argv[2]);
  602.     if (restartit) {
  603.         struct stat stbuf;
  604.         int ret;
  605.  
  606.         ret = stat(argv[2], &stbuf);
  607.         if (restartit == 1) {
  608.             if (ret < 0) {
  609.                 perror(argv[2]);
  610.                 return (0);
  611.             }
  612.             restart_point = stbuf.st_size;
  613.         } else {
  614.             if (ret == 0) {
  615.                 int overbose;
  616.  
  617.                 overbose = verbose;
  618.                 if (debug == 0)
  619.                     verbose = -1;
  620.                 if (command("MDTM %s", argv[1]) == COMPLETE) {
  621.                     int yy, mo, day, hour, min, sec;
  622.                     struct tm *tm;
  623.                     verbose = overbose;
  624.                     sscanf(reply_string,
  625.                         "%*s %04d%02d%02d%02d%02d%02d",
  626.                         &yy, &mo, &day, &hour, &min, &sec);
  627.                     tm = gmtime(&stbuf.st_mtime);
  628.                     tm->tm_mon++;
  629.                     if (tm->tm_year > yy%100)
  630.                         return (1);
  631.                     else if (tm->tm_year == yy%100) {
  632.                         if (tm->tm_mon > mo)
  633.                             return (1);
  634.                     } else if (tm->tm_mon == mo) {
  635.                         if (tm->tm_mday > day)
  636.                             return (1);
  637.                     } else if (tm->tm_mday == day) {
  638.                         if (tm->tm_hour > hour)
  639.                             return (1);
  640.                     } else if (tm->tm_hour == hour) {
  641.                         if (tm->tm_min > min)
  642.                             return (1);
  643.                     } else if (tm->tm_min == min) {
  644.                         if (tm->tm_sec > sec)
  645.                             return (1);
  646.                     }
  647.                 } else {
  648.                     fputs(reply_string, stdout);
  649.                     verbose = overbose;
  650.                     return (0);
  651.                 }
  652.             }
  653.         }
  654.     }
  655.  
  656.     recvrequest("RETR", argv[2], argv[1], mode,
  657.         argv[1] != oldargv1 || argv[2] != oldargv2);
  658.     restart_point = 0;
  659.     return (0);
  660. }
  661.  
  662. mabort()
  663. {
  664.     int ointer;
  665.     extern jmp_buf jabort;
  666.  
  667.     printf("\n");
  668.     (void) fflush(stdout);
  669.     if (mflag && fromatty) {
  670.         ointer = interactive;
  671.         interactive = 1;
  672.         if (confirm("Continue with", mname)) {
  673.             interactive = ointer;
  674.             longjmp(jabort,0);
  675.         }
  676.         interactive = ointer;
  677.     }
  678.     mflag = 0;
  679.     longjmp(jabort,0);
  680. }
  681.  
  682. /*
  683.  * Get multiple files.
  684.  */
  685. mget(argc, argv)
  686.     char *argv[];
  687. {
  688.     char *cp, *tp, *tp2, tmpbuf[MAXPATHLEN];
  689.     int ointer, (*oldintr)(), mabort();
  690.     extern jmp_buf jabort;
  691.  
  692.     if (argc < 2) {
  693.         (void) strcat(line, " ");
  694.         printf("(remote-files) ");
  695.         (void) gets(&line[strlen(line)]);
  696.         makeargv();
  697.         argc = margc;
  698.         argv = margv;
  699.     }
  700.     if (argc < 2) {
  701.         printf("usage:%s remote-files\n", argv[0]);
  702.         code = -1;
  703.         return;
  704.     }
  705.     mname = argv[0];
  706.     mflag = 1;
  707.     oldintr = signal(SIGINT,mabort);
  708.     (void) setjmp(jabort);
  709.     while ((cp = remglob(argv,proxy)) != NULL) {
  710.         if (*cp == '\0') {
  711.             mflag = 0;
  712.             continue;
  713.         }
  714.         if (mflag && confirm(argv[0], cp)) {
  715.             tp = cp;
  716.             if (mcase) {
  717.                 while (*tp && !islower(*tp)) {
  718.                     tp++;
  719.                 }
  720.                 if (!*tp) {
  721.                     tp = cp;
  722.                     tp2 = tmpbuf;
  723.                     while ((*tp2 = *tp) != NULL) {
  724.                         if (isupper(*tp2)) {
  725.                             *tp2 = 'a' + *tp2 - 'A';
  726.                         }
  727.                         tp++;
  728.                         tp2++;
  729.                     }
  730.                 }
  731.                 tp = tmpbuf;
  732.             }
  733.             if (ntflag) {
  734.                 tp = dotrans(tp);
  735.             }
  736.             if (mapflag) {
  737.                 tp = domap(tp);
  738.             }
  739.             recvrequest("RETR", tp, cp, "w",
  740.                 tp != cp || !interactive);
  741.             if (!mflag && fromatty) {
  742.                 ointer = interactive;
  743.                 interactive = 1;
  744.                 if (confirm("Continue with","mget")) {
  745.                     mflag++;
  746.                 }
  747.                 interactive = ointer;
  748.             }
  749.         }
  750.     }
  751.     (void) signal(SIGINT,oldintr);
  752.     mflag = 0;
  753. }
  754.  
  755. char *
  756. remglob(argv,doswitch)
  757.     char *argv[];
  758.     int doswitch;
  759. {
  760.     char temp[16];
  761.     static char buf[MAXPATHLEN];
  762.     static FILE *ftemp = NULL;
  763.     static char **args;
  764.     int oldverbose, oldhash;
  765.     char *cp, *mode;
  766.  
  767.     if (!mflag) {
  768.         if (!doglob) {
  769.             args = NULL;
  770.         }
  771.         else {
  772.             if (ftemp) {
  773.                 (void) fclose(ftemp);
  774.                 ftemp = NULL;
  775.             }
  776.         }
  777.         return(NULL);
  778.     }
  779.     if (!doglob) {
  780.         if (args == NULL)
  781.             args = argv;
  782.         if ((cp = *++args) == NULL)
  783.             args = NULL;
  784.         return (cp);
  785.     }
  786.     if (ftemp == NULL) {
  787.         (void) strcpy(temp, "/tmp/ftpXXXXXX");
  788.         (void) mktemp(temp);
  789.         oldverbose = verbose, verbose = 0;
  790.         oldhash = hash, hash = 0;
  791.         if (doswitch) {
  792.             pswitch(!proxy);
  793.         }
  794.         for (mode = "w"; *++argv != NULL; mode = "a")
  795.             recvrequest ("NLST", temp, *argv, mode, 0);
  796.         if (doswitch) {
  797.             pswitch(!proxy);
  798.         }
  799.         verbose = oldverbose; hash = oldhash;
  800.         ftemp = fopen(temp, "r");
  801.         (void) unlink(temp);
  802.         if (ftemp == NULL) {
  803.             printf("can't find list of remote files, oops\n");
  804.             return (NULL);
  805.         }
  806.     }
  807.     if (fgets(buf, sizeof (buf), ftemp) == NULL) {
  808.         (void) fclose(ftemp), ftemp = NULL;
  809.         return (NULL);
  810.     }
  811.     if ((cp = index(buf, '\n')) != NULL)
  812.         *cp = '\0';
  813.     return (buf);
  814. }
  815.  
  816. char *
  817. onoff(bool)
  818.     int bool;
  819. {
  820.  
  821.     return (bool ? "on" : "off");
  822. }
  823.  
  824. /*
  825.  * Show status.
  826.  */
  827. /*ARGSUSED*/
  828. status(argc, argv)
  829.     char *argv[];
  830. {
  831.     int i;
  832.  
  833.     if (connected)
  834.         printf("Connected to %s.\n", hostname);
  835.     else
  836.         printf("Not connected.\n");
  837.     if (!proxy) {
  838.         pswitch(1);
  839.         if (connected) {
  840.             printf("Connected for proxy commands to %s.\n", hostname);
  841.         }
  842.         else {
  843.             printf("No proxy connection.\n");
  844.         }
  845.         pswitch(0);
  846.     }
  847.     printf("Mode: %s; Type: %s; Form: %s; Structure: %s\n",
  848.         modename, typename, formname, structname);
  849.     printf("Verbose: %s; Bell: %s; Prompting: %s; Globbing: %s\n", 
  850.         onoff(verbose), onoff(bell), onoff(interactive),
  851.         onoff(doglob));
  852.     printf("Store unique: %s; Receive unique: %s\n", onoff(sunique),
  853.         onoff(runique));
  854.     printf("Case: %s; CR stripping: %s\n",onoff(mcase),onoff(crflag));
  855.     if (ntflag) {
  856.         printf("Ntrans: (in) %s (out) %s\n", ntin,ntout);
  857.     }
  858.     else {
  859.         printf("Ntrans: off\n");
  860.     }
  861.     if (mapflag) {
  862.         printf("Nmap: (in) %s (out) %s\n", mapin, mapout);
  863.     }
  864.     else {
  865.         printf("Nmap: off\n");
  866.     }
  867.     printf("Hash mark printing: %s; Use of PORT cmds: %s\n",
  868.         onoff(hash), onoff(sendport));
  869.     if (macnum > 0) {
  870.         printf("Macros:\n");
  871.         for (i=0; i<macnum; i++) {
  872.             printf("\t%s\n",macros[i].mac_name);
  873.         }
  874.     }
  875.     code = 0;
  876. }
  877.  
  878. /*
  879.  * Set beep on cmd completed mode.
  880.  */
  881. /*VARARGS*/
  882. setbell()
  883. {
  884.  
  885.     bell = !bell;
  886.     printf("Bell mode %s.\n", onoff(bell));
  887.     code = bell;
  888. }
  889.  
  890. /*
  891.  * Turn on packet tracing.
  892.  */
  893. /*VARARGS*/
  894. settrace()
  895. {
  896.  
  897.     trace = !trace;
  898.     printf("Packet tracing %s.\n", onoff(trace));
  899.     code = trace;
  900. }
  901.  
  902. /*
  903.  * Toggle hash mark printing during transfers.
  904.  */
  905. /*VARARGS*/
  906. sethash()
  907. {
  908.  
  909.     hash = !hash;
  910.     printf("Hash mark printing %s", onoff(hash));
  911.     code = hash;
  912.     if (hash)
  913.         printf(" (%d bytes/hash mark)", 1024);
  914.     printf(".\n");
  915. }
  916.  
  917. /*
  918.  * Turn on printing of server echo's.
  919.  */
  920. /*VARARGS*/
  921. setverbose()
  922. {
  923.  
  924.     verbose = !verbose;
  925.     printf("Verbose mode %s.\n", onoff(verbose));
  926.     code = verbose;
  927. }
  928.  
  929. /*
  930.  * Toggle PORT cmd use before each data connection.
  931.  */
  932. /*VARARGS*/
  933. setport()
  934. {
  935.  
  936.     sendport = !sendport;
  937.     printf("Use of PORT cmds %s.\n", onoff(sendport));
  938.     code = sendport;
  939. }
  940.  
  941. /*
  942.  * Turn on interactive prompting
  943.  * during mget, mput, and mdelete.
  944.  */
  945. /*VARARGS*/
  946. setprompt()
  947. {
  948.  
  949.     interactive = !interactive;
  950.     printf("Interactive mode %s.\n", onoff(interactive));
  951.     code = interactive;
  952. }
  953.  
  954. /*
  955.  * Toggle metacharacter interpretation
  956.  * on local file names.
  957.  */
  958. /*VARARGS*/
  959. setglob()
  960. {
  961.     
  962.     doglob = !doglob;
  963.     printf("Globbing %s.\n", onoff(doglob));
  964.     code = doglob;
  965. }
  966.  
  967. /*
  968.  * Set debugging mode on/off and/or
  969.  * set level of debugging.
  970.  */
  971. /*VARARGS*/
  972. setdebug(argc, argv)
  973.     char *argv[];
  974. {
  975.     int val;
  976.  
  977.     if (argc > 1) {
  978.         val = atoi(argv[1]);
  979.         if (val < 0) {
  980.             printf("%s: bad debugging value.\n", argv[1]);
  981.             code = -1;
  982.             return;
  983.         }
  984.     } else
  985.         val = !debug;
  986.     debug = val;
  987.     if (debug)
  988.         options |= SO_DEBUG;
  989.     else
  990.         options &= ~SO_DEBUG;
  991.     printf("Debugging %s (debug=%d).\n", onoff(debug), debug);
  992.     code = debug > 0;
  993. }
  994.  
  995. /*
  996.  * Set current working directory
  997.  * on remote machine.
  998.  */
  999. cd(argc, argv)
  1000.     char *argv[];
  1001. {
  1002.  
  1003.     if (argc < 2) {
  1004.         (void) strcat(line, " ");
  1005.         printf("(remote-directory) ");
  1006.         (void) gets(&line[strlen(line)]);
  1007.         makeargv();
  1008.         argc = margc;
  1009.         argv = margv;
  1010.     }
  1011.     if (argc < 2) {
  1012.         printf("usage:%s remote-directory\n", argv[0]);
  1013.         code = -1;
  1014.         return;
  1015.     }
  1016.     if (command("CWD %s", argv[1]) == ERROR && code == 500) {
  1017.         if (verbose)
  1018.             printf("CWD command not recognized, trying XCWD\n");
  1019.         (void) command("XCWD %s", argv[1]);
  1020.     }
  1021. }
  1022.  
  1023. /*
  1024.  * Set current working directory
  1025.  * on local machine.
  1026.  */
  1027. lcd(argc, argv)
  1028.     char *argv[];
  1029. {
  1030.     char buf[MAXPATHLEN];
  1031.  
  1032.     if (argc < 2)
  1033.         argc++, argv[1] = home;
  1034.     if (argc != 2) {
  1035.         printf("usage:%s local-directory\n", argv[0]);
  1036.         code = -1;
  1037.         return;
  1038.     }
  1039.     if (!globulize(&argv[1])) {
  1040.         code = -1;
  1041.         return;
  1042.     }
  1043.     if (chdir(argv[1]) < 0) {
  1044.         perror(argv[1]);
  1045.         code = -1;
  1046.         return;
  1047.     }
  1048.     printf("Local directory now %s\n", getwd(buf));
  1049.     code = 0;
  1050. }
  1051.  
  1052. /*
  1053.  * Delete a single file.
  1054.  */
  1055. delete(argc, argv)
  1056.     char *argv[];
  1057. {
  1058.  
  1059.     if (argc < 2) {
  1060.         (void) strcat(line, " ");
  1061.         printf("(remote-file) ");
  1062.         (void) gets(&line[strlen(line)]);
  1063.         makeargv();
  1064.         argc = margc;
  1065.         argv = margv;
  1066.     }
  1067.     if (argc < 2) {
  1068.         printf("usage:%s remote-file\n", argv[0]);
  1069.         code = -1;
  1070.         return;
  1071.     }
  1072.     (void) command("DELE %s", argv[1]);
  1073. }
  1074.  
  1075. /*
  1076.  * Delete multiple files.
  1077.  */
  1078. mdelete(argc, argv)
  1079.     char *argv[];
  1080. {
  1081.     char *cp;
  1082.     int ointer, (*oldintr)(), mabort();
  1083.     extern jmp_buf jabort;
  1084.  
  1085.     if (argc < 2) {
  1086.         (void) strcat(line, " ");
  1087.         printf("(remote-files) ");
  1088.         (void) gets(&line[strlen(line)]);
  1089.         makeargv();
  1090.         argc = margc;
  1091.         argv = margv;
  1092.     }
  1093.     if (argc < 2) {
  1094.         printf("usage:%s remote-files\n", argv[0]);
  1095.         code = -1;
  1096.         return;
  1097.     }
  1098.     mname = argv[0];
  1099.     mflag = 1;
  1100.     oldintr = signal(SIGINT, mabort);
  1101.     (void) setjmp(jabort);
  1102.     while ((cp = remglob(argv,0)) != NULL) {
  1103.         if (*cp == '\0') {
  1104.             mflag = 0;
  1105.             continue;
  1106.         }
  1107.         if (mflag && confirm(argv[0], cp)) {
  1108.             (void) command("DELE %s", cp);
  1109.             if (!mflag && fromatty) {
  1110.                 ointer = interactive;
  1111.                 interactive = 1;
  1112.                 if (confirm("Continue with", "mdelete")) {
  1113.                     mflag++;
  1114.                 }
  1115.                 interactive = ointer;
  1116.             }
  1117.         }
  1118.     }
  1119.     (void) signal(SIGINT, oldintr);
  1120.     mflag = 0;
  1121. }
  1122.  
  1123. /*
  1124.  * Rename a remote file.
  1125.  */
  1126. renamefile(argc, argv)
  1127.     char *argv[];
  1128. {
  1129.  
  1130.     if (argc < 2) {
  1131.         (void) strcat(line, " ");
  1132.         printf("(from-name) ");
  1133.         (void) gets(&line[strlen(line)]);
  1134.         makeargv();
  1135.         argc = margc;
  1136.         argv = margv;
  1137.     }
  1138.     if (argc < 2) {
  1139. usage:
  1140.         printf("%s from-name to-name\n", argv[0]);
  1141.         code = -1;
  1142.         return;
  1143.     }
  1144.     if (argc < 3) {
  1145.         (void) strcat(line, " ");
  1146.         printf("(to-name) ");
  1147.         (void) gets(&line[strlen(line)]);
  1148.         makeargv();
  1149.         argc = margc;
  1150.         argv = margv;
  1151.     }
  1152.     if (argc < 3) 
  1153.         goto usage;
  1154.     if (command("RNFR %s", argv[1]) == CONTINUE)
  1155.         (void) command("RNTO %s", argv[2]);
  1156. }
  1157.  
  1158. /*
  1159.  * Get a directory listing
  1160.  * of remote files.
  1161.  */
  1162. ls(argc, argv)
  1163.     char *argv[];
  1164. {
  1165.     char *cmd;
  1166.  
  1167.     if (argc < 2)
  1168.         argc++, argv[1] = NULL;
  1169.     if (argc < 3)
  1170.         argc++, argv[2] = "-";
  1171.     if (argc > 3) {
  1172.         printf("usage: %s remote-directory local-file\n", argv[0]);
  1173.         code = -1;
  1174.         return;
  1175.     }
  1176.     cmd = argv[0][0] == 'n' ? "NLST" : "LIST";
  1177.     if (strcmp(argv[2], "-") && !globulize(&argv[2])) {
  1178.         code = -1;
  1179.         return;
  1180.     }
  1181.     if (strcmp(argv[2], "-") && *argv[2] != '|')
  1182.         if (!globulize(&argv[2]) || !confirm("output to local-file:", argv[2])) {
  1183.             code = -1;
  1184.             return;
  1185.     }
  1186.     recvrequest(cmd, argv[2], argv[1], "w", 0);
  1187. }
  1188.  
  1189. /*
  1190.  * Get a directory listing
  1191.  * of multiple remote files.
  1192.  */
  1193. mls(argc, argv)
  1194.     char *argv[];
  1195. {
  1196.     char *cmd, mode[1], *dest;
  1197.     int ointer, i, (*oldintr)(), mabort();
  1198.     extern jmp_buf jabort;
  1199.  
  1200.     if (argc < 2) {
  1201.         (void) strcat(line, " ");
  1202.         printf("(remote-files) ");
  1203.         (void) gets(&line[strlen(line)]);
  1204.         makeargv();
  1205.         argc = margc;
  1206.         argv = margv;
  1207.     }
  1208.     if (argc < 3) {
  1209.         (void) strcat(line, " ");
  1210.         printf("(local-file) ");
  1211.         (void) gets(&line[strlen(line)]);
  1212.         makeargv();
  1213.         argc = margc;
  1214.         argv = margv;
  1215.     }
  1216.     if (argc < 3) {
  1217.         printf("usage:%s remote-files local-file\n", argv[0]);
  1218.         code = -1;
  1219.         return;
  1220.     }
  1221.     dest = argv[argc - 1];
  1222.     argv[argc - 1] = NULL;
  1223.     if (strcmp(dest, "-") && *dest != '|')
  1224.         if (!globulize(&dest) || !confirm("output to local-file:", dest)) {
  1225.             code = -1;
  1226.             return;
  1227.     }
  1228.     cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
  1229.     mname = argv[0];
  1230.     mflag = 1;
  1231.     oldintr = signal(SIGINT, mabort);
  1232.     (void) setjmp(jabort);
  1233.     for (i = 1; mflag && i < argc-1; ++i) {
  1234.         *mode = (i == 1) ? 'w' : 'a';
  1235.         recvrequest(cmd, dest, argv[i], mode, 0);
  1236.         if (!mflag && fromatty) {
  1237.             ointer = interactive;
  1238.             interactive = 1;
  1239.             if (confirm("Continue with", argv[0])) {
  1240.                 mflag ++;
  1241.             }
  1242.             interactive = ointer;
  1243.         }
  1244.     }
  1245.     (void) signal(SIGINT, oldintr);
  1246.     mflag = 0;
  1247. }
  1248.  
  1249. /*
  1250.  * Do a shell escape
  1251.  */
  1252. /*ARGSUSED*/
  1253. shell(argc, argv)
  1254.     char *argv[];
  1255. {
  1256.     int pid, (*old1)(), (*old2)();
  1257.     char shellnam[40], *shell, *namep; 
  1258.     union wait status;
  1259.  
  1260.     old1 = signal (SIGINT, SIG_IGN);
  1261.     old2 = signal (SIGQUIT, SIG_IGN);
  1262.     if ((pid = fork()) == 0) {
  1263.         for (pid = 3; pid < 20; pid++)
  1264.             (void) close(pid);
  1265.         (void) signal(SIGINT, SIG_DFL);
  1266.         (void) signal(SIGQUIT, SIG_DFL);
  1267.         shell = getenv("SHELL");
  1268.         if (shell == NULL)
  1269.             shell = "/bin/sh";
  1270.         namep = rindex(shell,'/');
  1271.         if (namep == NULL)
  1272.             namep = shell;
  1273.         (void) strcpy(shellnam,"-");
  1274.         (void) strcat(shellnam, ++namep);
  1275.         if (strcmp(namep, "sh") != 0)
  1276.             shellnam[0] = '+';
  1277.         if (debug) {
  1278.             printf ("%s\n", shell);
  1279.             (void) fflush (stdout);
  1280.         }
  1281.         if (argc > 1) {
  1282.             execl(shell,shellnam,"-c",altarg,(char *)0);
  1283.         }
  1284.         else {
  1285.             execl(shell,shellnam,(char *)0);
  1286.         }
  1287.         perror(shell);
  1288.         code = -1;
  1289.         exit(1);
  1290.         }
  1291.     if (pid > 0)
  1292.         while (wait(&status) != pid)
  1293.             ;
  1294.     (void) signal(SIGINT, old1);
  1295.     (void) signal(SIGQUIT, old2);
  1296.     if (pid == -1) {
  1297.         perror("Try again later");
  1298.         code = -1;
  1299.     }
  1300.     else {
  1301.         code = 0;
  1302.     }
  1303.     return (0);
  1304. }
  1305.  
  1306. /*
  1307.  * Send new user information (re-login)
  1308.  */
  1309. user(argc, argv)
  1310.     int argc;
  1311.     char **argv;
  1312. {
  1313.     char acct[80], *getpass();
  1314.     int n, aflag = 0;
  1315.  
  1316.     if (argc < 2) {
  1317.         (void) strcat(line, " ");
  1318.         printf("(username) ");
  1319.         (void) gets(&line[strlen(line)]);
  1320.         makeargv();
  1321.         argc = margc;
  1322.         argv = margv;
  1323.     }
  1324.     if (argc > 4) {
  1325.         printf("usage: %s username [password] [account]\n", argv[0]);
  1326.         code = -1;
  1327.         return (0);
  1328.     }
  1329.     n = command("USER %s", argv[1]);
  1330.     if (n == CONTINUE) {
  1331.         if (argc < 3 )
  1332.             argv[2] = getpass("Password: "), argc++;
  1333.         n = command("PASS %s", argv[2]);
  1334.     }
  1335.     if (n == CONTINUE) {
  1336.         if (argc < 4) {
  1337.             printf("Account: "); (void) fflush(stdout);
  1338.             (void) fgets(acct, sizeof(acct) - 1, stdin);
  1339.             acct[strlen(acct) - 1] = '\0';
  1340.             argv[3] = acct; argc++;
  1341.         }
  1342.         n = command("ACCT %s", argv[3]);
  1343.         aflag++;
  1344.     }
  1345.     if (n != COMPLETE) {
  1346.         fprintf(stdout, "Login failed.\n");
  1347.         return (0);
  1348.     }
  1349.     if (!aflag && argc == 4) {
  1350.         (void) command("ACCT %s", argv[3]);
  1351.     }
  1352.     return (1);
  1353. }
  1354.  
  1355. /*
  1356.  * Print working directory.
  1357.  */
  1358. /*VARARGS*/
  1359. pwd()
  1360. {
  1361.     int oldverbose = verbose;
  1362.  
  1363.     /*
  1364.      * If we aren't verbose, this doesn't do anything!
  1365.      */
  1366.     verbose = 1;
  1367.     if (command("PWD") == ERROR && code == 500) {
  1368.         printf("PWD command not recognized, trying XPWD\n");
  1369.         (void) command("XPWD");
  1370.     }
  1371.     verbose = oldverbose;
  1372. }
  1373.  
  1374. /*
  1375.  * Make a directory.
  1376.  */
  1377. makedir(argc, argv)
  1378.     char *argv[];
  1379. {
  1380.  
  1381.     if (argc < 2) {
  1382.         (void) strcat(line, " ");
  1383.         printf("(directory-name) ");
  1384.         (void) gets(&line[strlen(line)]);
  1385.         makeargv();
  1386.         argc = margc;
  1387.         argv = margv;
  1388.     }
  1389.     if (argc < 2) {
  1390.         printf("usage: %s directory-name\n", argv[0]);
  1391.         code = -1;
  1392.         return;
  1393.     }
  1394.     if (command("MKD %s", argv[1]) == ERROR && code == 500) {
  1395.         if (verbose)
  1396.             printf("MKD command not recognized, trying XMKD\n");
  1397.         (void) command("XMKD %s", argv[1]);
  1398.     }
  1399. }
  1400.  
  1401. /*
  1402.  * Remove a directory.
  1403.  */
  1404. removedir(argc, argv)
  1405.     char *argv[];
  1406. {
  1407.  
  1408.     if (argc < 2) {
  1409.         (void) strcat(line, " ");
  1410.         printf("(directory-name) ");
  1411.         (void) gets(&line[strlen(line)]);
  1412.         makeargv();
  1413.         argc = margc;
  1414.         argv = margv;
  1415.     }
  1416.     if (argc < 2) {
  1417.         printf("usage: %s directory-name\n", argv[0]);
  1418.         code = -1;
  1419.         return;
  1420.     }
  1421.     if (command("RMD %s", argv[1]) == ERROR && code == 500) {
  1422.         if (verbose)
  1423.             printf("RMD command not recognized, trying XRMD\n");
  1424.         (void) command("XRMD %s", argv[1]);
  1425.     }
  1426. }
  1427.  
  1428. /*
  1429.  * Send a line, verbatim, to the remote machine.
  1430.  */
  1431. quote(argc, argv)
  1432.     char *argv[];
  1433. {
  1434.     int i;
  1435.     char buf[BUFSIZ];
  1436.  
  1437.     if (argc < 2) {
  1438.         (void) strcat(line, " ");
  1439.         printf("(command line to send) ");
  1440.         (void) gets(&line[strlen(line)]);
  1441.         makeargv();
  1442.         argc = margc;
  1443.         argv = margv;
  1444.     }
  1445.     if (argc < 2) {
  1446.         printf("usage: %s line-to-send\n", argv[0]);
  1447.         code = -1;
  1448.         return;
  1449.     }
  1450.     (void) strcpy(buf, argv[1]);
  1451.     for (i = 2; i < argc; i++) {
  1452.         (void) strcat(buf, " ");
  1453.         (void) strcat(buf, argv[i]);
  1454.     }
  1455.     if (command(buf) == PRELIM) {
  1456.         while (getreply(0) == PRELIM);
  1457.     }
  1458. }
  1459.  
  1460. /*
  1461.  * Send a SITE command to the remote machine.  The line
  1462.  * is sent almost verbatim to the remote machine, the
  1463.  * first argument is changed to SITE.
  1464.  */
  1465.  
  1466. site(argc, argv)
  1467.     char *argv[];
  1468. {
  1469.     int i;
  1470.     char buf[BUFSIZ];
  1471.  
  1472.     if (argc < 2) {
  1473.         (void) strcat(line, " ");
  1474.         printf("(arguments to SITE command) ");
  1475.         (void) gets(&line[strlen(line)]);
  1476.         makeargv();
  1477.         argc = margc;
  1478.         argv = margv;
  1479.     }
  1480.     if (argc < 2) {
  1481.         printf("usage: %s line-to-send\n", argv[0]);
  1482.         code = -1;
  1483.         return;
  1484.     }
  1485.     (void) strcpy(buf, "SITE ");
  1486.     (void) strcat(buf, argv[1]);
  1487.     for (i = 2; i < argc; i++) {
  1488.         (void) strcat(buf, " ");
  1489.         (void) strcat(buf, argv[i]);
  1490.     }
  1491.     if (command(buf) == PRELIM) {
  1492.         while (getreply(0) == PRELIM);
  1493.     }
  1494. }
  1495.  
  1496. do_chmod(argc, argv)
  1497.     char *argv[];
  1498. {
  1499.     if (argc == 2) {
  1500.         printf("usage: %s mode file-name\n", argv[0]);
  1501.         code = -1;
  1502.         return;
  1503.     }
  1504.     if (argc < 3) {
  1505.         (void) strcat(line, " ");
  1506.         printf("(mode and file-name) ");
  1507.         (void) gets(&line[strlen(line)]);
  1508.         makeargv();
  1509.         argc = margc;
  1510.         argv = margv;
  1511.     }
  1512.     if (argc != 3) {
  1513.         printf("usage: %s mode file-name\n", argv[0]);
  1514.         code = -1;
  1515.         return;
  1516.     }
  1517.     (void)command("SITE CHMOD %s %s", argv[1], argv[2]);
  1518. }
  1519.  
  1520. do_umask(argc, argv)
  1521.     char *argv[];
  1522. {
  1523.     int oldverbose = verbose;
  1524.  
  1525.     verbose = 1;
  1526.     (void) command(argc == 1 ? "SITE UMASK" : "SITE UMASK %s", argv[1]);
  1527.     verbose = oldverbose;
  1528. }
  1529.  
  1530. idle(argc, argv)
  1531.     char *argv[];
  1532. {
  1533.     int oldverbose = verbose;
  1534.  
  1535.     verbose = 1;
  1536.     (void) command(argc == 1 ? "SITE IDLE" : "SITE IDLE %s", argv[1]);
  1537.     verbose = oldverbose;
  1538. }
  1539.  
  1540. /*
  1541.  * Ask the other side for help.
  1542.  */
  1543. rmthelp(argc, argv)
  1544.     char *argv[];
  1545. {
  1546.     int oldverbose = verbose;
  1547.  
  1548.     verbose = 1;
  1549.     (void) command(argc == 1 ? "HELP" : "HELP %s", argv[1]);
  1550.     verbose = oldverbose;
  1551. }
  1552.  
  1553. /*
  1554.  * Terminate session and exit.
  1555.  */
  1556. /*VARARGS*/
  1557. quit()
  1558. {
  1559.  
  1560.     if (connected)
  1561.         disconnect();
  1562.     pswitch(1);
  1563.     if (connected) {
  1564.         disconnect();
  1565.     }
  1566.     exit(0);
  1567. }
  1568.  
  1569. /*
  1570.  * Terminate session, but don't exit.
  1571.  */
  1572. disconnect()
  1573. {
  1574.     extern FILE *cout;
  1575.     extern int data;
  1576.  
  1577.     if (!connected)
  1578.         return;
  1579.     (void) command("QUIT");
  1580.     if (cout) {
  1581.         (void) fclose(cout);
  1582.     }
  1583.     cout = NULL;
  1584.     connected = 0;
  1585.     data = -1;
  1586.     if (!proxy) {
  1587.         macnum = 0;
  1588.     }
  1589. }
  1590.  
  1591. confirm(cmd, file)
  1592.     char *cmd, *file;
  1593. {
  1594.     char line[BUFSIZ];
  1595.  
  1596.     if (!interactive)
  1597.         return (1);
  1598.     printf("%s %s? ", cmd, file);
  1599.     (void) fflush(stdout);
  1600.     (void) gets(line);
  1601.     return (*line != 'n' && *line != 'N');
  1602. }
  1603.  
  1604. fatal(msg)
  1605.     char *msg;
  1606. {
  1607.  
  1608.     fprintf(stderr, "ftp: %s\n", msg);
  1609.     exit(1);
  1610. }
  1611.  
  1612. /*
  1613.  * Glob a local file name specification with
  1614.  * the expectation of a single return value.
  1615.  * Can't control multiple values being expanded
  1616.  * from the expression, we return only the first.
  1617.  */
  1618. globulize(cpp)
  1619.     char **cpp;
  1620. {
  1621.     char **globbed;
  1622.  
  1623.     if (!doglob)
  1624.         return (1);
  1625.     globbed = glob(*cpp);
  1626.     if (globerr != NULL) {
  1627.         printf("%s: %s\n", *cpp, globerr);
  1628.         if (globbed) {
  1629.             blkfree(globbed);
  1630.             free(globbed);
  1631.         }
  1632.         return (0);
  1633.     }
  1634.     if (globbed) {
  1635.         *cpp = *globbed++;
  1636.         /* don't waste too much memory */
  1637.         if (*globbed) {
  1638.             blkfree(globbed);
  1639.             free(globbed);
  1640.         }
  1641.     }
  1642.     return (1);
  1643. }
  1644.  
  1645. account(argc,argv)
  1646.     int argc;
  1647.     char **argv;
  1648. {
  1649.     char acct[50], *getpass(), *ap;
  1650.  
  1651.     if (argc > 1) {
  1652.         ++argv;
  1653.         --argc;
  1654.         (void) strncpy(acct,*argv,49);
  1655.         acct[49] = '\0';
  1656.         while (argc > 1) {
  1657.             --argc;
  1658.             ++argv;
  1659.             (void) strncat(acct,*argv, 49-strlen(acct));
  1660.         }
  1661.         ap = acct;
  1662.     }
  1663.     else {
  1664.         ap = getpass("Account:");
  1665.     }
  1666.     (void) command("ACCT %s", ap);
  1667. }
  1668.  
  1669. jmp_buf abortprox;
  1670.  
  1671. proxabort()
  1672. {
  1673.     extern int proxy;
  1674.  
  1675.     if (!proxy) {
  1676.         pswitch(1);
  1677.     }
  1678.     if (connected) {
  1679.         proxflag = 1;
  1680.     }
  1681.     else {
  1682.         proxflag = 0;
  1683.     }
  1684.     pswitch(0);
  1685.     longjmp(abortprox,1);
  1686. }
  1687.  
  1688. doproxy(argc,argv)
  1689.     int argc;
  1690.     char *argv[];
  1691. {
  1692.     int (*oldintr)(), proxabort();
  1693.     register struct cmd *c;
  1694.     struct cmd *getcmd();
  1695.     extern struct cmd cmdtab[];
  1696.     extern jmp_buf abortprox;
  1697.  
  1698.     if (argc < 2) {
  1699.         (void) strcat(line, " ");
  1700.         printf("(command) ");
  1701.         (void) gets(&line[strlen(line)]);
  1702.         makeargv();
  1703.         argc = margc;
  1704.         argv = margv;
  1705.     }
  1706.     if (argc < 2) {
  1707.         printf("usage:%s command\n", argv[0]);
  1708.         code = -1;
  1709.         return;
  1710.     }
  1711.     c = getcmd(argv[1]);
  1712.     if (c == (struct cmd *) -1) {
  1713.         printf("?Ambiguous command\n");
  1714.         (void) fflush(stdout);
  1715.         code = -1;
  1716.         return;
  1717.     }
  1718.     if (c == 0) {
  1719.         printf("?Invalid command\n");
  1720.         (void) fflush(stdout);
  1721.         code = -1;
  1722.         return;
  1723.     }
  1724.     if (!c->c_proxy) {
  1725.         printf("?Invalid proxy command\n");
  1726.         (void) fflush(stdout);
  1727.         code = -1;
  1728.         return;
  1729.     }
  1730.     if (setjmp(abortprox)) {
  1731.         code = -1;
  1732.         return;
  1733.     }
  1734.     oldintr = signal(SIGINT, proxabort);
  1735.     pswitch(1);
  1736.     if (c->c_conn && !connected) {
  1737.         printf("Not connected\n");
  1738.         (void) fflush(stdout);
  1739.         pswitch(0);
  1740.         (void) signal(SIGINT, oldintr);
  1741.         code = -1;
  1742.         return;
  1743.     }
  1744.     (*c->c_handler)(argc-1, argv+1);
  1745.     if (connected) {
  1746.         proxflag = 1;
  1747.     }
  1748.     else {
  1749.         proxflag = 0;
  1750.     }
  1751.     pswitch(0);
  1752.     (void) signal(SIGINT, oldintr);
  1753. }
  1754.  
  1755. setcase()
  1756. {
  1757.     mcase = !mcase;
  1758.     printf("Case mapping %s.\n", onoff(mcase));
  1759.     code = mcase;
  1760. }
  1761.  
  1762. setcr()
  1763. {
  1764.     crflag = !crflag;
  1765.     printf("Carriage Return stripping %s.\n", onoff(crflag));
  1766.     code = crflag;
  1767. }
  1768.  
  1769. setntrans(argc,argv)
  1770.     int argc;
  1771.     char *argv[];
  1772. {
  1773.     if (argc == 1) {
  1774.         ntflag = 0;
  1775.         printf("Ntrans off.\n");
  1776.         code = ntflag;
  1777.         return;
  1778.     }
  1779.     ntflag++;
  1780.     code = ntflag;
  1781.     (void) strncpy(ntin, argv[1], 16);
  1782.     ntin[16] = '\0';
  1783.     if (argc == 2) {
  1784.         ntout[0] = '\0';
  1785.         return;
  1786.     }
  1787.     (void) strncpy(ntout, argv[2], 16);
  1788.     ntout[16] = '\0';
  1789. }
  1790.  
  1791. char *
  1792. dotrans(name)
  1793.     char *name;
  1794. {
  1795.     static char new[MAXPATHLEN];
  1796.     char *cp1, *cp2 = new;
  1797.     register int i, ostop, found;
  1798.  
  1799.     for (ostop = 0; *(ntout + ostop) && ostop < 16; ostop++);
  1800.     for (cp1 = name; *cp1; cp1++) {
  1801.         found = 0;
  1802.         for (i = 0; *(ntin + i) && i < 16; i++) {
  1803.             if (*cp1 == *(ntin + i)) {
  1804.                 found++;
  1805.                 if (i < ostop) {
  1806.                     *cp2++ = *(ntout + i);
  1807.                 }
  1808.                 break;
  1809.             }
  1810.         }
  1811.         if (!found) {
  1812.             *cp2++ = *cp1;
  1813.         }
  1814.     }
  1815.     *cp2 = '\0';
  1816.     return(new);
  1817. }
  1818.  
  1819. setnmap(argc, argv)
  1820.     int argc;
  1821.     char *argv[];
  1822. {
  1823.     char *cp;
  1824.  
  1825.     if (argc == 1) {
  1826.         mapflag = 0;
  1827.         printf("Nmap off.\n");
  1828.         code = mapflag;
  1829.         return;
  1830.     }
  1831.     if (argc < 3) {
  1832.         (void) strcat(line, " ");
  1833.         printf("(mapout) ");
  1834.         (void) gets(&line[strlen(line)]);
  1835.         makeargv();
  1836.         argc = margc;
  1837.         argv = margv;
  1838.     }
  1839.     if (argc < 3) {
  1840.         printf("Usage: %s [mapin mapout]\n",argv[0]);
  1841.         code = -1;
  1842.         return;
  1843.     }
  1844.     mapflag = 1;
  1845.     code = 1;
  1846.     cp = index(altarg, ' ');
  1847.     if (proxy) {
  1848.         while(*++cp == ' ');
  1849.         altarg = cp;
  1850.         cp = index(altarg, ' ');
  1851.     }
  1852.     *cp = '\0';
  1853.     (void) strncpy(mapin, altarg, MAXPATHLEN - 1);
  1854.     while (*++cp == ' ');
  1855.     (void) strncpy(mapout, cp, MAXPATHLEN - 1);
  1856. }
  1857.  
  1858. char *
  1859. domap(name)
  1860.     char *name;
  1861. {
  1862.     static char new[MAXPATHLEN];
  1863.     register char *cp1 = name, *cp2 = mapin;
  1864.     char *tp[9], *te[9];
  1865.     int i, toks[9], toknum = 0, match = 1;
  1866.  
  1867.     for (i=0; i < 9; ++i) {
  1868.         toks[i] = 0;
  1869.     }
  1870.     while (match && *cp1 && *cp2) {
  1871.         switch (*cp2) {
  1872.             case '\\':
  1873.                 if (*++cp2 != *cp1) {
  1874.                     match = 0;
  1875.                 }
  1876.                 break;
  1877.             case '$':
  1878.                 if (*(cp2+1) >= '1' && (*cp2+1) <= '9') {
  1879.                     if (*cp1 != *(++cp2+1)) {
  1880.                         toks[toknum = *cp2 - '1']++;
  1881.                         tp[toknum] = cp1;
  1882.                         while (*++cp1 && *(cp2+1)
  1883.                             != *cp1);
  1884.                         te[toknum] = cp1;
  1885.                     }
  1886.                     cp2++;
  1887.                     break;
  1888.                 }
  1889.                 /* FALLTHROUGH */
  1890.             default:
  1891.                 if (*cp2 != *cp1) {
  1892.                     match = 0;
  1893.                 }
  1894.                 break;
  1895.         }
  1896.         if (match && *cp1) {
  1897.             cp1++;
  1898.         }
  1899.         if (match && *cp2) {
  1900.             cp2++;
  1901.         }
  1902.     }
  1903.     if (!match && *cp1) /* last token mismatch */
  1904.     {
  1905.         toks[toknum] = 0;
  1906.     }
  1907.     cp1 = new;
  1908.     *cp1 = '\0';
  1909.     cp2 = mapout;
  1910.     while (*cp2) {
  1911.         match = 0;
  1912.         switch (*cp2) {
  1913.             case '\\':
  1914.                 if (*(cp2 + 1)) {
  1915.                     *cp1++ = *++cp2;
  1916.                 }
  1917.                 break;
  1918.             case '[':
  1919. LOOP:
  1920.                 if (*++cp2 == '$' && isdigit(*(cp2+1))) { 
  1921.                     if (*++cp2 == '0') {
  1922.                         char *cp3 = name;
  1923.  
  1924.                         while (*cp3) {
  1925.                             *cp1++ = *cp3++;
  1926.                         }
  1927.                         match = 1;
  1928.                     }
  1929.                     else if (toks[toknum = *cp2 - '1']) {
  1930.                         char *cp3 = tp[toknum];
  1931.  
  1932.                         while (cp3 != te[toknum]) {
  1933.                             *cp1++ = *cp3++;
  1934.                         }
  1935.                         match = 1;
  1936.                     }
  1937.                 }
  1938.                 else {
  1939.                     while (*cp2 && *cp2 != ',' && 
  1940.                         *cp2 != ']') {
  1941.                         if (*cp2 == '\\') {
  1942.                             cp2++;
  1943.                         }
  1944.                         else if (*cp2 == '$' &&
  1945.                                    isdigit(*(cp2+1))) {
  1946.                             if (*++cp2 == '0') {
  1947.                                char *cp3 = name;
  1948.  
  1949.                                while (*cp3) {
  1950.                                 *cp1++ = *cp3++;
  1951.                                }
  1952.                             }
  1953.                             else if (toks[toknum =
  1954.                                 *cp2 - '1']) {
  1955.                                char *cp3=tp[toknum];
  1956.  
  1957.                                while (cp3 !=
  1958.                                   te[toknum]) {
  1959.                                 *cp1++ = *cp3++;
  1960.                                }
  1961.                             }
  1962.                         }
  1963.                         else if (*cp2) {
  1964.                             *cp1++ = *cp2++;
  1965.                         }
  1966.                     }
  1967.                     if (!*cp2) {
  1968.                         printf("nmap: unbalanced brackets\n");
  1969.                         return(name);
  1970.                     }
  1971.                     match = 1;
  1972.                     cp2--;
  1973.                 }
  1974.                 if (match) {
  1975.                     while (*++cp2 && *cp2 != ']') {
  1976.                           if (*cp2 == '\\' && *(cp2 + 1)) {
  1977.                             cp2++;
  1978.                           }
  1979.                     }
  1980.                     if (!*cp2) {
  1981.                         printf("nmap: unbalanced brackets\n");
  1982.                         return(name);
  1983.                     }
  1984.                     break;
  1985.                 }
  1986.                 switch (*++cp2) {
  1987.                     case ',':
  1988.                         goto LOOP;
  1989.                     case ']':
  1990.                         break;
  1991.                     default:
  1992.                         cp2--;
  1993.                         goto LOOP;
  1994.                 }
  1995.                 break;
  1996.             case '$':
  1997.                 if (isdigit(*(cp2 + 1))) {
  1998.                     if (*++cp2 == '0') {
  1999.                         char *cp3 = name;
  2000.  
  2001.                         while (*cp3) {
  2002.                             *cp1++ = *cp3++;
  2003.                         }
  2004.                     }
  2005.                     else if (toks[toknum = *cp2 - '1']) {
  2006.                         char *cp3 = tp[toknum];
  2007.  
  2008.                         while (cp3 != te[toknum]) {
  2009.                             *cp1++ = *cp3++;
  2010.                         }
  2011.                     }
  2012.                     break;
  2013.                 }
  2014.                 /* intentional drop through */
  2015.             default:
  2016.                 *cp1++ = *cp2;
  2017.                 break;
  2018.         }
  2019.         cp2++;
  2020.     }
  2021.     *cp1 = '\0';
  2022.     if (!*new) {
  2023.         return(name);
  2024.     }
  2025.     return(new);
  2026. }
  2027.  
  2028. setsunique()
  2029. {
  2030.     sunique = !sunique;
  2031.     printf("Store unique %s.\n", onoff(sunique));
  2032.     code = sunique;
  2033. }
  2034.  
  2035. setrunique()
  2036. {
  2037.     runique = !runique;
  2038.     printf("Receive unique %s.\n", onoff(runique));
  2039.     code = runique;
  2040. }
  2041.  
  2042. /* change directory to perent directory */
  2043. cdup()
  2044. {
  2045.     if (command("CDUP") == ERROR && code == 500) {
  2046.         if (verbose)
  2047.             printf("CDUP command not recognized, trying XCUP\n");
  2048.         (void) command("XCUP");
  2049.     }
  2050. }
  2051.  
  2052. /* restart transfer at specific point */
  2053. restart(argc, argv)
  2054.     int argc;
  2055.     char *argv[];
  2056. {
  2057.     extern long atol();
  2058.     if (argc != 2)
  2059.         printf("restart: offset not specified\n");
  2060.     else {
  2061.         restart_point = atol(argv[1]);
  2062.         printf("restarting at %ld. %s\n", restart_point,
  2063.             "execute get, put or append to initiate transfer");
  2064.     }
  2065. }
  2066.  
  2067. /* show remote system type */
  2068. syst()
  2069. {
  2070.     (void) command("SYST");
  2071. }
  2072.  
  2073. macdef(argc, argv)
  2074.     int argc;
  2075.     char *argv[];
  2076. {
  2077.     char *tmp;
  2078.     int c;
  2079.  
  2080.     if (macnum == 16) {
  2081.         printf("Limit of 16 macros have already been defined\n");
  2082.         code = -1;
  2083.         return;
  2084.     }
  2085.     if (argc < 2) {
  2086.         (void) strcat(line, " ");
  2087.         printf("(macro name) ");
  2088.         (void) gets(&line[strlen(line)]);
  2089.         makeargv();
  2090.         argc = margc;
  2091.         argv = margv;
  2092.     }
  2093.     if (argc != 2) {
  2094.         printf("Usage: %s macro_name\n",argv[0]);
  2095.         code = -1;
  2096.         return;
  2097.     }
  2098.     if (interactive) {
  2099.         printf("Enter macro line by line, terminating it with a null line\n");
  2100.     }
  2101.     (void) strncpy(macros[macnum].mac_name, argv[1], 8);
  2102.     if (macnum == 0) {
  2103.         macros[macnum].mac_start = macbuf;
  2104.     }
  2105.     else {
  2106.         macros[macnum].mac_start = macros[macnum - 1].mac_end + 1;
  2107.     }
  2108.     tmp = macros[macnum].mac_start;
  2109.     while (tmp != macbuf+4096) {
  2110.         if ((c = getchar()) == EOF) {
  2111.             printf("macdef:end of file encountered\n");
  2112.             code = -1;
  2113.             return;
  2114.         }
  2115.         if ((*tmp = c) == '\n') {
  2116.             if (tmp == macros[macnum].mac_start) {
  2117.                 macros[macnum++].mac_end = tmp;
  2118.                 code = 0;
  2119.                 return;
  2120.             }
  2121.             if (*(tmp-1) == '\0') {
  2122.                 macros[macnum++].mac_end = tmp - 1;
  2123.                 code = 0;
  2124.                 return;
  2125.             }
  2126.             *tmp = '\0';
  2127.         }
  2128.         tmp++;
  2129.     }
  2130.     while (1) {
  2131.         while ((c = getchar()) != '\n' && c != EOF)
  2132.             /* LOOP */;
  2133.         if (c == EOF || getchar() == '\n') {
  2134.             printf("Macro not defined - 4k buffer exceeded\n");
  2135.             code = -1;
  2136.             return;
  2137.         }
  2138.     }
  2139. }
  2140.  
  2141. /*
  2142.  * get size of file on remote machine
  2143.  */
  2144. sizecmd(argc, argv)
  2145.     char *argv[];
  2146. {
  2147.  
  2148.     if (argc < 2) {
  2149.         (void) strcat(line, " ");
  2150.         printf("(filename) ");
  2151.         (void) gets(&line[strlen(line)]);
  2152.         makeargv();
  2153.         argc = margc;
  2154.         argv = margv;
  2155.     }
  2156.     if (argc < 2) {
  2157.         printf("usage:%s filename\n", argv[0]);
  2158.         code = -1;
  2159.         return;
  2160.     }
  2161.     (void) command("SIZE %s", argv[1]);
  2162. }
  2163.  
  2164. /*
  2165.  * get last modification time of file on remote machine
  2166.  */
  2167. modtime(argc, argv)
  2168.     char *argv[];
  2169. {
  2170.     int overbose;
  2171.  
  2172.     if (argc < 2) {
  2173.         (void) strcat(line, " ");
  2174.         printf("(filename) ");
  2175.         (void) gets(&line[strlen(line)]);
  2176.         makeargv();
  2177.         argc = margc;
  2178.         argv = margv;
  2179.     }
  2180.     if (argc < 2) {
  2181.         printf("usage:%s filename\n", argv[0]);
  2182.         code = -1;
  2183.         return;
  2184.     }
  2185.     overbose = verbose;
  2186.     if (debug == 0)
  2187.         verbose = -1;
  2188.     if (command("MDTM %s", argv[1]) == COMPLETE) {
  2189.         int yy, mo, day, hour, min, sec;
  2190.         sscanf(reply_string, "%*s %04d%02d%02d%02d%02d%02d", &yy, &mo,
  2191.             &day, &hour, &min, &sec);
  2192.         /* might want to print this in local time */
  2193.         printf("%s\t%02d/%02d/%04d %02d:%02d:%02d GMT\n", argv[1],
  2194.             mo, day, yy, hour, min, sec);
  2195.     } else
  2196.         fputs(reply_string, stdout);
  2197.     verbose = overbose;
  2198. }
  2199.  
  2200. /*
  2201.  * show status on reomte machine
  2202.  */
  2203. rmtstatus(argc, argv)
  2204.     char *argv[];
  2205. {
  2206.     (void) command(argc > 1 ? "STAT %s" : "STAT" , argv[1]);
  2207. }
  2208.  
  2209. /*
  2210.  * get file if modtime is more recent than current file
  2211.  */
  2212. newer(argc, argv)
  2213.     char *argv[];
  2214. {
  2215.     if (getit(argc, argv, -1, "w"))
  2216.         printf("Local file \"%s\" is newer than remote file \"%s\"\n",
  2217.             argv[1], argv[2]);
  2218. }
  2219. @
  2220.  
  2221.  
  2222. 1.3
  2223. log
  2224. @New revision.
  2225. @
  2226. text
  2227. @d468 7
  2228. d476 1
  2229. @
  2230.  
  2231.  
  2232. 1.2
  2233. log
  2234. @Include netinet/in.h so that htons macro gets defined correctly.
  2235. @
  2236. text
  2237. @d2 1
  2238. a2 1
  2239.  * Copyright (c) 1985 Regents of the University of California.
  2240. d6 10
  2241. a15 5
  2242.  * provided that this notice is preserved and that due credit is given
  2243.  * to the University of California at Berkeley. The name of the University
  2244.  * may not be used to endorse or promote products derived from this
  2245.  * software without specific prior written permission. This software
  2246.  * is provided ``as is'' without express or implied warranty.
  2247. d19 1
  2248. a19 1
  2249. static char sccsid[] = "@@(#)cmds.c    5.7 (Berkeley) 3/14/88";
  2250. d25 3
  2251. a27 1
  2252. #include "ftp_var.h"
  2253. d37 3
  2254. a39 2
  2255. #include <sys/wait.h>
  2256. #include <netinet/in.h>
  2257. a44 1
  2258. extern    short gflag;
  2259. d49 3
  2260. d100 3
  2261. a102 1
  2262.         if (autologin)
  2263. d104 38
  2264. d290 1
  2265. a290 1
  2266.     char *oldargv1;
  2267. d322 1
  2268. d341 2
  2269. a342 1
  2270.     sendrequest(cmd, argv[1], argv[2]);
  2271. d406 2
  2272. a407 1
  2273.                 sendrequest((sunique) ? "STOU" : "STOR", cp,tp);
  2274. d430 1
  2275. a430 1
  2276.                             argv[i], tp);
  2277. d445 1
  2278. a445 1
  2279.             if (gargs)
  2280. d447 2
  2281. d456 1
  2282. a456 1
  2283.                        *cpp, tp);
  2284. d467 1
  2285. a467 1
  2286.         if (gargs != NULL)
  2287. d469 2
  2288. d476 12
  2289. d491 1
  2290. a491 1
  2291. get(argc, argv)
  2292. d493 1
  2293. d496 1
  2294. d515 1
  2295. a515 1
  2296.         return;
  2297. d527 2
  2298. d531 1
  2299. a531 1
  2300.         return;
  2301. d552 1
  2302. a552 1
  2303.     if (loc && ntflag) {
  2304. d554 1
  2305. a554 2
  2306.     }
  2307.     if (loc && mapflag) {
  2308. d556 52
  2309. d609 5
  2310. a613 1
  2311.     recvrequest("RETR", argv[2], argv[1], "w");
  2312. d693 2
  2313. a694 1
  2314.             recvrequest("RETR", tp, cp, "w");
  2315. d749 1
  2316. a749 1
  2317.             recvrequest ("NLST", temp, *argv, mode);
  2318. d867 1
  2319. a867 1
  2320.         printf(" (%d bytes/hash mark)", BUFSIZ);
  2321. d970 5
  2322. a974 1
  2323.     (void) command("CWD %s", argv[1]);
  2324. d1130 1
  2325. a1130 1
  2326.     cmd = argv[0][0] == 'l' ? "NLST" : "LIST";
  2327. d1140 1
  2328. a1140 1
  2329.     recvrequest(cmd, argv[2], argv[1], "w");
  2330. d1189 1
  2331. a1189 1
  2332.         recvrequest(cmd, dest, argv[i], mode);
  2333. d1267 1
  2334. a1267 1
  2335.     char acct[80], *mygetpass();
  2336. d1286 1
  2337. a1286 1
  2338.             argv[2] = mygetpass("Password: "), argc++;
  2339. d1315 1
  2340. d1317 9
  2341. a1325 1
  2342.     (void) command("PWD");
  2343. d1348 5
  2344. a1352 1
  2345.     (void) command("MKD %s", argv[1]);
  2346. d1375 5
  2347. a1379 1
  2348.     (void) command("RMD %s", argv[1]);
  2349. d1415 80
  2350. d1582 1
  2351. a1582 1
  2352.         if (globbed)
  2353. d1584 2
  2354. d1591 1
  2355. a1591 1
  2356.         if (*globbed)
  2357. d1593 2
  2358. a1599 1
  2359.  
  2360. d1603 1
  2361. a1603 1
  2362.     char acct[50], *mygetpass(), *ap;
  2363. d1609 1
  2364. a1609 1
  2365.         acct[50] = '\0';
  2366. d1618 1
  2367. a1618 1
  2368.         ap = mygetpass("Account:");
  2369. d1819 1
  2370. a1819 1
  2371.     int i, toks[9], toknum, match = 1;
  2372. d1843 1
  2373. a1843 1
  2374.                 /* intentional drop through */
  2375. d1850 1
  2376. a1850 1
  2377.         if (*cp1) {
  2378. d1853 1
  2379. a1853 1
  2380.         if (*cp2) {
  2381. d1857 4
  2382. d1999 26
  2383. a2024 1
  2384.     (void) command("CDUP");
  2385. d2085 2
  2386. a2086 1
  2387.         while ((c = getchar()) != '\n' && c != EOF);
  2388. d2093 79
  2389. @
  2390.  
  2391.  
  2392. 1.1
  2393. log
  2394. @Initial revision
  2395. @
  2396. text
  2397. @d31 1
  2398. @
  2399.